#pragma once
#include <stdint.h>
#include <stdbool.h>

// Ring buffer structure
// head  - write index
// tail  - read index
// size  - buffer size (must be power of 2)
// mask  - size - 1, used for fast modulo
// buf   - pointer to the data buffer
typedef struct {
    volatile uint16_t head;
    volatile uint16_t tail;
    uint16_t size;
    uint16_t mask;
    uint8_t *buf;
} ringbuf_t;

// Initialize the ring buffer
// rb   - pointer to ring buffer
// buf  - pointer to user-provided buffer array
// size - size of buffer (must be power of 2)
void rb_init(ringbuf_t *rb, uint8_t *buf, uint16_t size);

// Put one byte into ring buffer (safe for ISR and main)
// Returns true if successful, false if buffer full
bool rb_put(ringbuf_t *rb, uint8_t data);

// Get one byte from ring buffer (safe for ISR and main)
// Returns true if successful, false if buffer empty
bool rb_get(ringbuf_t *rb, uint8_t *data);

// Get the number of bytes currently stored in buffer
uint16_t rb_count(ringbuf_t *rb);

// Check if buffer is empty
bool rb_is_empty(ringbuf_t *rb);

// Check if buffer is full
bool rb_is_full(ringbuf_t *rb);